﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Samples.ConsoleClient
{
	class Program
	{
		private static Sepal.PrettyObjectPrinter.Printer PrettyColorPrinter = new Sepal.PrettyObjectPrinter.Printer();
		// private static Albatross.Common.WCF.IWcfRequestProcessorForDotNetClient configChannelFactoryProxy = GetServiceProxyWithConfigFileSettings();
		// private static Albatross.Common.WCF.IWcfRequestProcessorForDotNetClient progChannelFactoryProxy = GetServiceProxyWithProgrammaticallyCreatedSettings();
		//private static Albatross.ClientSide.WCF.RequestProcessorProxyForDotNetClient configRequestProxy = new Albatross.ClientSide.WCF.RequestProcessorProxyForDotNetClient();
		private static Albatross.ClientSide.WCF.RequestProcessorProxyForDotNetClient progRequestProxy = GetRPProxyWithProgrammaticallyCreatedSettings();
		static void Main( string[] args )
		{
			// A few sample functions that use the Albatross Framework

			// Using the RequestProcessorProxy (config or code)
			// This is the recommended way to use Albatross for (non Silverlight) DotNet clients
			RPGetBorrowerOneRequest();
			//RPProxyGetBorrowerOneRequestAsync();
			//RPGetBorrowerWithWrap();
			//RPGetBorrowerAndListBorrowersOneCallMultipleRequests();
			//RPGetBorrowerRaiseException(); // Uncomment this line to see how to deal with exceptions
			//RPGetBorrowerRaiseException2();

			// Using the ChannelFactoryProxy (config or code)
			// Another way to use Albatross
			//GetBorrowerOneRequest();
			//GetBorrowerWithWrap();
			//GetBorrowerAndListBorrowersOneCallMultipleRequests();
			//GetBorrowerRaiseException(); 

			// Using the Dispatcher
			// Another way to use Albatross
			//GetBorrowerOneRequestDispatchConfig();

			System.Console.WriteLine( "" );
			System.Console.WriteLine( "Done!" );
			System.Console.Read();

		}

		// Using the RequestProcessorProxy 
		private static void RPGetBorrowerOneRequest()
		{
			List<Albatross.Common.Messaging.DotNetRequest> entityRequest = new List<Albatross.Common.Messaging.DotNetRequest>();
			for ( int i = 0; i < 1; i++ )
			{
				entityRequest.Add( new Samples.Contract.RequestsAndResponses.GetBorrowerI() );
			}


			System.Console.WriteLine( "Calling GetBorrower() based on config settings" );
			System.Console.WriteLine();
			progRequestProxy.ClientCredentials.UserName.UserName = "Bob";
			progRequestProxy.ClientCredentials.UserName.Password = "Newheart";
			//      var response = (Samples.Contract.RequestsAndResponses.GetBorrowerO)configRequestProxy.Process(entityRequest.ToArray(  )).First();
			var response = ( Samples.Contract.RequestsAndResponses.GetBorrowerO )progRequestProxy.Process( entityRequest.ToArray() ).First();
			//System.Console.WriteLine("First Name: " + response.MyBorrower.FirstName.ToString());
			//System.Console.WriteLine("Last Name: " + response.MyBorrower.LastName.ToString());
			// This prints the whole entity, in color!
			// That's the reason for the references to Jayrock.Json and Sepal.PrettyObjectPrinter
			PrettyColorPrinter.Print( response.MyBorrower );

			//System.Console.WriteLine( "Calling GetBorrower() based on programmatically created settings" );
			//System.Console.WriteLine();
			//response = ( Samples.Contract.RequestsAndResponses.GetBorrowerO )progRequestProxy.Process( entityRequest ).First();
			//PrettyColorPrinter.Print( response.MyBorrower );
		}

		//private static void RPGetBorrowerWithWrap()
		//{
		//  var entityRequest = new Samples.Contract.RequestsAndResponses.GetBorrowerWithWrapI();
		//  entityRequest.message2 = "Place values that would be relevant to all requests in your custom request.";

		//  System.Console.WriteLine("Calling GetBorrowerWithWrapI() based on config settings");
		//  System.Console.WriteLine();
		//  var response = (Samples.Contract.RequestsAndResponses.GetBorrowerO)configRequestProxy.Process(entityRequest).First();
		//  PrettyColorPrinter.Print(response.MyBorrower);
		//}

		//private static void RPProxyGetBorrowerOneRequestAsync()
		//{
		//  System.Console.WriteLine("Calling proxy.ProcessAsync()");
		//  configRequestProxy.ProcessAsync(GetBorrowerOneRequestWithProxyConfigAsynCallBack, new Samples.Contract.RequestsAndResponses.GetBorrowerI());
		//  System.Console.WriteLine("End of RPProxyGetBorrowerOneRequestAsync");
		//}

		//private static void GetBorrowerOneRequestWithProxyConfigAsynCallBack(IList<Albatross.Common.Messaging.Response> responses)
		//{

		//  System.Console.WriteLine("In the call back - GetBorrowerOneRequestWithProxyConfigAsynCallBack()");
		//  var response = (Samples.Contract.RequestsAndResponses.GetBorrowerO)responses[0];
		//  System.Console.WriteLine("First Name: " + response.MyBorrower.FirstName.ToString());
		//  System.Console.WriteLine("Last Name: " + response.MyBorrower.LastName.ToString());
		//  PrettyColorPrinter.Print(response.MyBorrower);
		//}

		//private static void RPGetBorrowerAndListBorrowersOneCallMultipleRequests()
		//{
		//  var entityRequest = new Samples.Contract.RequestsAndResponses.GetBorrowerI();
		//  var entityRequest2 = new Samples.Contract.RequestsAndResponses.ListBorrowersI();

		//  System.Console.WriteLine("Calling GetBorrower() and ListBorrowers() with one call to the server.");
		//  System.Console.WriteLine();
		//  var responses = configRequestProxy.Process(entityRequest, entityRequest2);
		//  for (int i = 0; i < responses.Length; i++)
		//  {
		//    if (responses[i].GetType() == typeof(Samples.Contract.RequestsAndResponses.GetBorrowerO))
		//    {
		//      Samples.Contract.RequestsAndResponses.GetBorrowerO GetBorrowerResponse = (Samples.Contract.RequestsAndResponses.GetBorrowerO)responses[i];
		//      PrettyColorPrinter.Print(GetBorrowerResponse.MyBorrower);
		//    }
		//    else if (responses[i].GetType() == typeof(Samples.Contract.RequestsAndResponses.ListBorrowersO))
		//    {
		//      Samples.Contract.RequestsAndResponses.ListBorrowersO ListBorrowersResponse = (Samples.Contract.RequestsAndResponses.ListBorrowersO)responses[i];
		//      PrettyColorPrinter.Print(ListBorrowersResponse.MyBorrowers);
		//    }
		//  }
		//}

		//private static void RPGetBorrowerRaiseException()
		//{
		//  // Make sure you have a try...catch when calling server functions
		//  // To simplify the samples we do not do it in every client function
		//  try
		//  {
		//    var entityRequest = new Samples.Contract.RequestsAndResponses.GetBorrowerRaisesExceptionI();

		//    System.Console.WriteLine("Calling GetBorrowerRaiseException().");
		//    System.Console.WriteLine();
		//    var response = configRequestProxy.Process(entityRequest).First();

		//    if (response.StatusType != 0)
		//    { // If an exception occurs on the server, Albatross will set the StatusCode to ErrorCode.HandlerNotFound or ErrorCode.UnHandledException
		//      switch (response.StatusType)
		//      {
		//        case (int)Albatross.Common.Exceptions.ErrorType.HandlerNotFound:
		//          System.Console.WriteLine("Error: HandlerNotFound!");
		//          break;
		//        case (int)Albatross.Common.Exceptions.ErrorType.RequestProcessorUnHandledException:
		//          System.Console.WriteLine("Error: UnHandledException = " + response.StatusInfo);
		//          break;
		//        default:
		//          break;
		//      }
		//    }
		//    else
		//    {
		//      System.Console.WriteLine();
		//      Samples.Contract.RequestsAndResponses.GetBorrowerO GetBorrowerResponse = (Samples.Contract.RequestsAndResponses.GetBorrowerO)response;
		//      System.Console.WriteLine("First Name: " + GetBorrowerResponse.MyBorrower.FirstName.ToString());
		//    }
		//  }
		//  catch (System.Exception ex)
		//  {
		//    // You need this to handle client exceptions (timeout, etc...)
		//    System.Console.WriteLine("Exception: " + ex.ToString());

		//  }
		//}

		//private static void RPGetBorrowerRaiseException2()
		//{
		//  // Make sure you have a try...catch when calling server functions
		//  // To simplify the samples we do not do it in every client function
		//  try
		//  {
		//    var entityRequest = new Samples.Contract.RequestsAndResponses.GetBorrowerRaisesException2I();

		//    System.Console.WriteLine("Calling GetBorrowerRaiseException2().");
		//    System.Console.WriteLine();
		//    var response = configRequestProxy.Process(entityRequest).First();

		//    if (response.StatusType == -1)
		//    { // If an exception occurs on the server, in this example we handled it and set the StatusType to -1
		//      System.Console.WriteLine();
		//      Samples.Contract.RequestsAndResponses.GetBorrowerRaisesException2O GetBorrowerResponse = (Samples.Contract.RequestsAndResponses.GetBorrowerRaisesException2O)response;
		//      System.Console.WriteLine("Server Exception Message: " + GetBorrowerResponse.ExceptionMessage);
		//    }
		//    else
		//    {
		//      System.Console.WriteLine();
		//      Samples.Contract.RequestsAndResponses.GetBorrowerO GetBorrowerResponse = (Samples.Contract.RequestsAndResponses.GetBorrowerO)response;
		//      System.Console.WriteLine("First Name: " + GetBorrowerResponse.MyBorrower.FirstName.ToString());
		//    }
		//  }
		//  catch (System.Exception ex)
		//  {
		//    // You need this to handle client exceptions (timeout, etc...)
		//    System.Console.WriteLine("Exception: " + ex.ToString());

		//  }
		//}

		//// Using the ChannelFactoryProxy 

		//private static void GetBorrowerWithWrap()
		//{
		//  var entityRequest = new Samples.Contract.RequestsAndResponses.GetBorrowerWithWrapI();
		//  entityRequest.message2 = "Place values that would be relevant to all requests in your custom request.";

		//  System.Console.WriteLine("Calling GetBorrowerWithWrapI() based on config settings");
		//  System.Console.WriteLine();
		//  var response = (Samples.Contract.RequestsAndResponses.GetBorrowerO)configChannelFactoryProxy.Process(entityRequest).First();
		//  PrettyColorPrinter.Print(response.MyBorrower);
		//}

		//private static void GetBorrowerOneRequest()
		//{
		//    var entityRequest = new Samples.Contract.RequestsAndResponses.GetBorrowerI();

		//  System.Console.WriteLine("Calling GetBorrower() based on config settings");
		//  System.Console.WriteLine();
		//  var response = ( Samples.Contract.RequestsAndResponses.GetBorrowerO )configChannelFactoryProxy.Process( entityRequest ).First();
		//  System.Console.WriteLine("First Name: " + response.MyBorrower.FirstName.ToString());
		//  System.Console.WriteLine("Last Name: " + response.MyBorrower.LastName.ToString());
		//  // This prints the whole entity, in color!
		//  // That's the reason for the references to Jayrock.Json and Sepal.PrettyObjectPrinter
		//  PrettyColorPrinter.Print(response.MyBorrower);

		//  System.Console.WriteLine("Calling GetBorrower() based on programmatically created settings");
		//  System.Console.WriteLine();
		//  response = ( Samples.Contract.RequestsAndResponses.GetBorrowerO )progChannelFactoryProxy.Process( entityRequest ).First();
		//  PrettyColorPrinter.Print(response.MyBorrower);
		//}

		//// Using the Dispatcher
		//private static void GetBorrowerOneRequestDispatchConfig()
		//{
		//  Albatross.ClientSide.ComponentRegistration.RegisterDispatcherForWcfUsage();
		//  Albatross.ClientSide.WCF.WcfDispatcherForDotNetClient Dispatcher = new Albatross.ClientSide.WCF.WcfDispatcherForDotNetClient();

		//  Dispatcher.Add(new Samples.Contract.RequestsAndResponses.GetBorrowerI()); // add as many requests as needed

		//  System.Console.WriteLine("Calling GetBorrower() based on config settings");
		//  System.Console.WriteLine();
		//  var response = Dispatcher.Get<Samples.Contract.RequestsAndResponses.GetBorrowerO>(); // on the first 'Get' Albatross will make a call to the server a retrieve all responses

		//  System.Console.WriteLine("First Name: " + response.MyBorrower.FirstName.ToString());
		//  System.Console.WriteLine("Last Name: " + response.MyBorrower.LastName.ToString());
		//  PrettyColorPrinter.Print(response.MyBorrower);
		//}


		////private static void GetBorrowerOneRequestDispatchCodeAsync()
		////{
		////  Albatross.ClientSide.ComponentRegistration.RegisterDispatcherForWcfUsage();
		////  Albatross.ClientSide.Messaging.Dispatcher Dispatcher = new Albatross.ClientSide.Messaging.Dispatcher(ProxyWithProgrammaticallyCreatedSettings());

		////  System.Console.WriteLine("Calling Dispatcher.GetResponsesAsync()");
		////  Dispatcher.GetResponsesAsync(GetBorrowerOneRequestWithProxyConfigAsynCallBack, new Samples.Contract.RequestsAndResponses.GetBorrowerI());
		////  System.Console.WriteLine("End of GetBorrowerOneRequestDispatchConfigAsync");

		////}

		//private static void GetBorrowerAndListBorrowersOneCallMultipleRequests()
		//{
		//    var entityRequest = new Samples.Contract.RequestsAndResponses.GetBorrowerI();
		//    var entityRequest2 = new Samples.Contract.RequestsAndResponses.ListBorrowersI();

		//  System.Console.WriteLine("Calling GetBorrower() and ListBorrowers() with one call to the server.");
		//  System.Console.WriteLine();
		//  var responses = configChannelFactoryProxy.Process( entityRequest, entityRequest2);
		//  for (int i = 0; i < responses.Length; i++ )
		//  {
		//      if ( responses[ i ].GetType() == typeof( Samples.Contract.RequestsAndResponses.GetBorrowerO ) )
		//    {
		//        Samples.Contract.RequestsAndResponses.GetBorrowerO GetBorrowerResponse = ( Samples.Contract.RequestsAndResponses.GetBorrowerO )responses[ i ];
		//      PrettyColorPrinter.Print(GetBorrowerResponse.MyBorrower);
		//    }
		//      else if ( responses[ i ].GetType() == typeof( Samples.Contract.RequestsAndResponses.ListBorrowersO ) )
		//    {
		//        Samples.Contract.RequestsAndResponses.ListBorrowersO ListBorrowersResponse = ( Samples.Contract.RequestsAndResponses.ListBorrowersO )responses[ i ];
		//      PrettyColorPrinter.Print(ListBorrowersResponse.MyBorrowers);
		//    }
		//  }
		//}

		//private static void GetBorrowerRaiseException()
		//{
		//  // Make sure you have a try...catch when calling server functions
		//  // To simplify the samples we do not do it in every client function
		//  try
		//  {
		//    var entityRequest = new Samples.Contract.RequestsAndResponses.GetBorrowerRaisesExceptionI();

		//    System.Console.WriteLine("Calling GetBorrowerRaiseException().");
		//    System.Console.WriteLine();
		//    var response = configChannelFactoryProxy.Process(entityRequest).First();

		//    if (response.StatusType != 0)
		//    { // If an exception occurs on the server, Albatross will set the StatusCode to ErrorCode.HandlerNotFound or ErrorCode.UnHandledException
		//      switch (response.StatusType)
		//      {
		//        case (int)Albatross.Common.Exceptions.ErrorType.HandlerNotFound:
		//          System.Console.WriteLine("Error: HandlerNotFound!");
		//          break;
		//        case (int)Albatross.Common.Exceptions.ErrorType.RequestProcessorUnHandledException:
		//          System.Console.WriteLine("Error: UnHandledException = " + response.StatusInfo);
		//          break;
		//        default:
		//          break;
		//      }
		//    } else {
		//      System.Console.WriteLine();
		//      Samples.Contract.RequestsAndResponses.GetBorrowerO GetBorrowerResponse = (Samples.Contract.RequestsAndResponses.GetBorrowerO)response;
		//      System.Console.WriteLine("First Name: " + GetBorrowerResponse.MyBorrower.FirstName.ToString());
		//    }
		//  }
		//  catch (System.Exception ex)
		//  {
		//    // You need this to handle client exceptions (timeout, etc...)
		//    System.Console.WriteLine("Exception: " + ex.ToString());

		//  }
		//}

		////private static void GetBorrowerOneRequestAsync()
		////{
		////  var entityRequest = new Samples.Contract.RequestsAndResponses.GetBorrowerI();

		////  System.Console.WriteLine("Calling GetBorrower() based on config settings");
		////  System.Console.WriteLine();
		////  configChannelFactoryProxy.Process(entityRequest);
		////}

		////private static void GetBorrowerOneRequestAsyncCallback()
		////{
		////  System.Console.WriteLine("First Name: " + response.MyBorrower.FirstName.ToString());
		////  System.Console.WriteLine("Last Name: " + response.MyBorrower.LastName.ToString());
		////  // This prints the whole entity, in color!
		////  // That's the reason for the references to Jayrock.Json and Sepal.PrettyObjectPrinter
		////  PrettyColorPrinter.Print(response.MyBorrower);

		////  System.Console.WriteLine("Calling GetBorrower() based on programmatically created settings");
		////  System.Console.WriteLine();
		////  response = (Samples.Contract.RequestsAndResponses.GetBorrowerO)progChannelFactoryProxy.Process(entityRequest).First();
		////  PrettyColorPrinter.Print(response.MyBorrower);
		////}

		//    public static Albatross.Common.WCF.IWcfRequestProcessorForDotNetClient GetServiceProxyWithConfigFileSettings()
		//    {
		//        return new ChannelFactory<Albatross.Common.WCF.IWcfRequestProcessorForDotNetClient>( "WcfRequestProcessor.EndPoint" ).CreateChannel(  );
		//    }

		//    public static Albatross.Common.WCF.IWcfRequestProcessorForDotNetClient GetServiceProxyWithProgrammaticallyCreatedSettings()
		//    {
		//        var binding = new BasicHttpBinding();
		//        var address = new EndpointAddress( "http://localhost:8000/RequestProcessor.svc" );
		//        return new ChannelFactory<Albatross.Common.WCF.IWcfRequestProcessorForDotNetClient>( binding, address ).CreateChannel(  );
		//    }

		public static Albatross.ClientSide.WCF.RequestProcessorProxyForDotNetClient GetRPProxyWithProgrammaticallyCreatedSettings()
		{
			var binding = new Albatross.WCF.Extenions.Bindings.ClearUsernameBinding();
			// binding.SetMessageVersion( MessageVersion.Soap12 );


			var compression = new Albatross.WCF.Extenions.ServiceModel.Channels.CompressionBindingElement();
			compression.Algorithm = Albatross.WCF.Extenions.ServiceModel.Channels.CompressionAlgorithm.GZip;
			compression.Level = Albatross.WCF.Extenions.ServiceModel.Channels.CompressionLevel.Normal;

			binding.ClearElement.Add( compression );

			binding.ClearElement.Add( new TextMessageEncodingBindingElement()
			{
				MessageVersion = MessageVersion.Soap12
			} );
			binding.ClearElement.Add( SecurityBindingElement.CreateUserNameOverTransportBindingElement() );
			binding.ClearElement.Add( new Albatross.WCF.Extenions.Bindings.AutoSecuredHttpTransportElement() );



			var address = new EndpointAddress( "http://Home.Sepal.ws:8000/RequestProcessor.svc" );
			return new Albatross.ClientSide.WCF.RequestProcessorProxyForDotNetClient( binding, address );
		}
	}
}
